package natsio

import (
	"encoding/json"
	"gitee.com/liukexing/mqbroker/core/driver/logger"
	"gitee.com/liukexing/mqbroker/core/typedef"
	"github.com/nats-io/go-nats"
)

type NatsReplyHandle struct {
	handel *ReplyHandle
}

func (c *NatsReplyHandle) HandleMessage(msg *nats.Msg) {
	c.handel.Reply = msg.Reply
	data, ok := c.handel.Praise(msg.Data)
	if ok {
		return
	}
	logger.Error(typedef.ErrInfo{
		Info: Config.Info,
		Err:  c.handel.Process(data),
	})
}

type ReplyHandle struct {
	Reply  string
	parent *NatsPubSub
}

func (m *ReplyHandle) Praise(v []byte) (interface{}, bool) {
	req := typedef.RequestData{}
	if logger.CheckErr(typedef.ErrInfo{
		Info: Config.Info,
		Err:  json.Unmarshal(v, &req),
	}) {
		return nil, true
	}
	return req, false
}

func (m *ReplyHandle) Process(data interface{}) error {
	req := data.(typedef.RequestData)
	if v, ok := m.parent.ReplyFunc.Load(req.Topic); !ok {
		return m.Response(typedef.ReplyData{
			Topic: req.Topic,
			ReqID: req.ReqID,
			Error: true,
			Data:  "Reply func  Not Exist",
		})
	} else {
		handle := v.(typedef.ReplyHandle)
		reqdata, ok := handle.Praise(req.Data)
		if ok {
			return m.Response(typedef.ReplyData{
				Topic: req.Topic,
				ReqID: req.ReqID,
				Error: true,
				Data:  "Data Praise Error",
			})
		}
		rsp, err := handle.Process(reqdata)
		if err != nil {
			return m.Response(typedef.ReplyData{
				Topic: req.Topic,
				ReqID: req.ReqID,
				Error: true,
				Data:  err.Error(),
			})
		}
		return m.Response(typedef.ReplyData{
			Topic: req.Topic,
			ReqID: req.ReqID,
			Error: false,
			Data:  rsp,
		})
	}

}

func (m *ReplyHandle) Response(data typedef.ReplyData) error {
	jsv, err := json.Marshal(data)
	if logger.CheckErr(typedef.ErrInfo{
		Info: Config.Info,
		Err:  err,
	}) {
		return err
	}
	v, _ := m.parent.Subscriber.Load("Request")
	return v.(*typedef.NatsSub).Conn.Publish(m.Reply, jsv)
}
